﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using PokerService.Game;
using System.Threading;


namespace PokerService
{
    [DataContract]
    public class Table
    {
        private Deck deDeck;
        int raise;
        int stage;
        DateTime start = DateTime.Now;
        public Table(int tableID, string name, int stackes, int minBuyIn, int pot)
        {
            TableID = tableID;
            Name = name;
            Stackes = stackes;
            MinBuyIn = minBuyIn;
            WaitingList = new List<Player>();
            PlayingList = new List<Player>();
            

            deDeck = new Deck();
            Pot = pot;
            Raise = raise;
            Stage = stage;
            Thread t = new Thread(Dealer);
            t.Start();
        }

        [DataMember]
        public int TableID { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public int Stackes { get; set; }

        [DataMember]
        public int MinBuyIn { get; set; }

        [DataMember]
        public int Raise { get; set; }

        [DataMember]
        public int Stage { get; set; }

        [DataMember]
        public List<Player> PlayingList { get; set; }
        [DataMember]
        public List<Player> WaitingList { get; set; }

        [DataMember]
        public int Pot { get; set; }

        public Card Card1 { get; set; } ///when setting callbaack to all clientas about new card on the table
        public Card Card2 { get; set; }
        public Card Card3 { get; set; }
        public Card Card4 { get; set; }
        public Card Card5 { get; set; }



        private bool StartGame()
        {
            if (WaitingList.Count > 0)
            {
                foreach (Player p in WaitingList)
                {
                    //addd player
                    WaitingList.Add(p);
                }
            }

            if (PlayingList.Count >= 2)
            {
                
                return true;
                //foreach (Player p in PlayingList)
                //{
                //    p.Card1 = null;
                //    p.Card2 = null;
                //}
            }
            return false;
        }

        public void Dealer()
        {
            while (true)
            {

                if (StartGame())
                {
                    deDeck = new Deck();
                    Pot = 0;
                    foreach (Player p in PlayingList)
                    {
                        p.PlayerCallBack.updatePot(Pot);
                        p.Action = null;
                        p.IsPlaying = true;
                        p.IsYourTurn = false;
                    }

                    foreach (Player p in PlayingList)
                    {
                        p.PlayerCallBack.gameStarts("game stars in 3 sec");
                    }
                    Thread.Sleep(4000);
                    //1 2 cars for each player
                    foreach (Player p in PlayingList)
                    {
                        p.Card1 = deDeck.TakeRandomCard();
                        Thread.Sleep(100);
                        p.Card2 = deDeck.TakeRandomCard();
                        p.PlayerCallBack.giveCards(p.SeatNr, p.Card1.ToString(), p.Card2.ToString());
                    }

                    //foreach (Player p in PlayingList)
                    //{
                    //    while (p.Action==null)
                    //    {
                    //        Thread.Sleep(100);
                    //    }
                    //}
                    Thread.Sleep(3000);
                    //2  bid loop
                    //biding();
                    //3 3 cards on the table
                    Card1 = deDeck.TakeRandomCard();
                    Card2 = deDeck.TakeRandomCard();
                    Card3 = deDeck.TakeRandomCard();

                    foreach (Player x in PlayingList)
                    {
                        x.PlayerCallBack.updateCards(Card1.ToString(), 1);
                        x.PlayerCallBack.updateCards(Card2.ToString(), 2);
                        x.PlayerCallBack.updateCards(Card3.ToString(), 3);
                    }
                    //4 bid loop
                    //5 extra card
                    Thread.Sleep(1000);
                    Card4 = deDeck.TakeRandomCard();
                    foreach (Player x in PlayingList)
                    {
                        x.PlayerCallBack.updateCards(Card4.ToString(), 4);
                    }
                    //6 bid loop
                    //7 extra card
                    Thread.Sleep(1000);
                    Card5 = deDeck.TakeRandomCard();
                    foreach (Player x in PlayingList)
                    {
                        x.PlayerCallBack.updateCards(Card5.ToString(), 5);
                    }
                    //8 bid loop
                    foreach (Player p in PlayingList)
                    {
                        
                        while (p.IsPlaying && p.Action == null)
                        {
                            p.IsYourTurn = true;
                            foreach (Player x in PlayingList)
                            {
                                x.PlayerCallBack.updatePlayer(x.Username, x.MoneyOnTable, x.SeatNr, x.IsYourTurn, x.Action);
                            }
                            Thread.Sleep(1000);
                            if (Pot > 0)
                            {
                                p.PlayerCallBack.updateButtons(2, 10);
                            }
                            else
                            {
                                p.PlayerCallBack.updateButtons(1, 1);
                            }
                        }
                    }

                    int a = CheckForWinner();
                    foreach (Player x in PlayingList)
                    {
                        if (x.SeatNr == a)
                        {
                            x.MoneyOnTable += Pot;
                        }
                        x.PlayerCallBack.anounceWinner(a);
                        
                    }
                    Thread.Sleep(10000);
                    //chech for winner in bid loop
                    foreach (Player x in PlayingList)
                    {
                        x.PlayerCallBack.updatePlayer(x.Username, x.MoneyOnTable, x.SeatNr, x.IsYourTurn, x.Action);
                    }
                    //foreach (Player p in PlayingList)
                    //{
                    //    p.PlayerCallBack.giveCards(p.SeatNr, " ", " ");
                    //}
                }
                Thread.Sleep(1000);
            }
        }

        public void biding()
        {
            
        }

        public int checkForPlayers()
        {
            int counter = 0;
            foreach (Player p in PlayingList)
            {
                if (p.IsPlaying == true)
                    counter++;
            }
            return counter;
        }

        public void setTurns()
        {
            foreach (Player p in PlayingList)
            {
                p.Turn = p.SeatNr;
            }
        }

        public int CheckForWinner()
        {
            if (checkForPlayers() == 1)
            {
                foreach (Player p in PlayingList)
                {
                    if (p.IsPlaying)
                    {
                        return p.SeatNr;
                    }
                }
            }
            

            foreach (Player p in PlayingList)
            {
                p.comboValue = 0;
            }


            List<Card> CardsOnTable = new List<Card>();
            CardsOnTable.Add(Card1);
            CardsOnTable.Add(Card2);
            CardsOnTable.Add(Card3);
            CardsOnTable.Add(Card4);
            CardsOnTable.Add(Card5);

            foreach (Player p in PlayingList)
            {//highest card
                int comboValue1 = (int) p.Card1.r;
                int comboValue2 = (int) p.Card2.r;
                if (comboValue1 > comboValue2)
                {
                    p.comboValue = comboValue1;
                }
                else
                {
                    p.comboValue = comboValue2;
                }

                //highest 2 cards
                foreach (Card c in CardsOnTable)
                {
                    if (c.r==p.Card1.r)
                    {
                        int comboValue = 100 + (int) c.r;
                        if (p.comboValue > comboValue)
                        {
                            p.comboValue = comboValue;
                        }
                    }
                    if (c.r == p.Card2.r)
                    {
                        int comboValue = 100 + (int)c.r;
                        if (p.comboValue > comboValue)
                        {
                            p.comboValue = comboValue;

                        }
                    }
                }

                //highest 3


                //foreach (Card c in CardsOnTable)
                //{
                //    if (c.r == p.Card1.r)
                //    {
                //        int comboValue = 100 + (int)c.r;
                //        if (p.comboValue > comboValue)
                //        {
                //            p.comboValue = comboValue;
                //        }
                //    }
                //    if (c.r == p.Card2.r)
                //    {
                //        int comboValue = 100 + (int)c.r;
                //        if (p.comboValue > comboValue)
                //        {
                //            p.comboValue = comboValue;

                //        }
                //    }
                //}


            }


            int bestComboSeatNr = 0;
            int bigestComboValue = 0;
            foreach (Player p in PlayingList)
            {
                if (p.comboValue>bigestComboValue)
                {
                    bestComboSeatNr = p.SeatNr;
                }
            }
            return bestComboSeatNr;
        }
    }
}
